#include "filehandler2.h"
#include <filesystem>
#include <QDebug>
#include <QRegularExpression>
#include <QFile>

FileHandler2::FileHandler2(const QString &file, QObject *parent) : QObject(parent), m_cachefile(file)
{

}

void FileHandler2::loadFile()
{
    m_process = new QProcess(this);
    QString file("./SaveDE&ENcry/SaveToolDe.exe");
    m_process->start(file, QStringList(m_cachefile));
    connect(m_process, &QProcess::finished, this, [this](){
        namespace fs = std::filesystem;
        qDebug() << m_cachefile << Qt::endl;
        fs::path filepath(m_cachefile.toStdString());
        fs::path generatedfile = filepath.replace_filename(fs::path("DataUnit.json"));
        if(!fs::exists(generatedfile)){
            qDebug() << "don't Exists!" << Qt::endl;
            emit json_generated(false);
        }else{
            m_jsonfile = QString::fromStdString(generatedfile.generic_string());
            qDebug() << "Exists!" << Qt::endl;
            emit json_generated(true);
        }
        m_process->disconnect(this);
//        process->disconnect(this);
    });
}

QMap<QString, QString> FileHandler2::loadJson()
{
    qDebug() << "Json File: " << m_jsonfile << Qt::endl;
    if(!m_jsonfile.isEmpty()){
//        file = new QFile(json_file);
        std::string jsonfile = m_jsonfile.toStdString();
        m_ifs.open(m_jsonfile.toStdString());
        qDebug() << "M_Jsonfile: " << m_jsonfile << Qt::endl;
//        std::cout << "Std String: " << m_jsonfile.toStdString() << std::endl;
        m_json = jsoncons::ojson::parse(m_ifs);
        m_ifs.close();
        QFile file(m_jsonfile);
        file.open(QIODevice::ReadOnly | QIODevice::Text);
        QString value = file.readAll();
        QRegularExpression re(":{.+?\"");
        auto match = re.match(value);
    //    QRegularExpressionMatch match;
        auto firstmatch = match.captured(0);
        re.setPattern("[A-Za-z0-9]+");
        m_nameid = re.match(firstmatch).captured(0);
        qDebug() << "NameID is " << m_nameid << Qt::endl;
        auto character = m_json.at_or_null("allUnit").at_or_null(m_nameid.toStdString()).at_or_null("q");
        std::cout << jsoncons::pretty_print(character) << std::endl;
//        auto name = character["q"];
//        file->open(QIODevice::ReadOnly | QIODevice::Text);
//        QString value = file->readAll();
//        QJsonParseError parserJsonErr;
//        document = QJsonDocument::fromJson(value.toUtf8(), &parserJsonErr);
//        if(!(parserJsonErr.error == QJsonParseError::NoError)){
//            qDebug() << tr("解析json文件错误");
//            return {};
//        }
//        file->flush();
//        file->close();
//        QRegularExpression re(":{.+?\"");
//        auto match = re.match(value);
//    //    QRegularExpressionMatch match;
//        auto firstmatch = match.captured(0);
//        re.setPattern("[A-Za-z0-9]+");
//        nameid = re.match(firstmatch).captured(0);
//        qDebug() << "Name ID = " << nameid << Qt::endl;
//        QJsonObject jsonObject = document.object();
//        auto character = jsonObject["allUnit"].toObject()[nameid].toObject()["q"].toObject();
    //    qDebug() << "Hello There" << jsonObject["allUnit"].toObject().keys()[0] << Qt::endl;
        auto name = character["q"]; //Array
        auto attack = character["1"]; //int
        auto defense = character["2"]; //int
        auto footSpeed = character["3"]; //int
        auto crit = character["7"]; //int
        auto guard = character["9"]; //int
        auto critValue = character["8"]; //int
        auto guardValue = character["qq"]; //int
        auto reputation = character["a"]; //int
        auto mpMax = character["b"]; //int
        auto mp = character["v"]; //int
        auto hpMax = character["c"]; //int
        auto hp = character["x"]; //int
        auto spMax = character["m"]; //int
        auto sp = character["n"]; //int
        auto talent = character["k"]; //int
        auto moveSpeed = character["qw"]; //int
        auto sex = character["r"]; //int 2 for male 1 for female
        auto race = character["t"];
        auto physicalFree = character["qe"]; //int
        auto magicFree = character["qr"]; //int
        auto fire = character["qt"]; //int
        auto froze = character["qy"]; //int
        auto thunder = character["qu"]; //int
        auto wind = character["qi"]; //int
        auto earth = character["qo"]; //int
        auto wood = character["qp"]; //int
        auto sword = character["qa"];
        auto spear = character["qs"];
        auto blade = character["qd"];
        auto fist = character["qf"];
        auto palm = character["qg"];
        auto finger = character["qh"];
        auto refineElixir = character["qj"];
        auto refineWeapon = character["qk"];
        auto geomancy = character["ql"];
        auto symbol = character["qz"];
        auto herbal = character["wq"];
        auto mine = character["ww"];
        auto mood = character["qx"];
        auto moodMax = character["qc"];
        auto abilityPoint = character["j"];
        auto life = character["u"];
        auto luck = character["4"];
        auto beauty = character["i"];
        auto healthMax = character["z"];
        auto energyMax = character["6"];

//        qDebug() << "Here" << Qt::endl;
        QMap<QString, QString> map{
            {"lastname", QString::fromStdString(name[0].as_string())},
            {"firstname", QString::fromStdString(name[1].as_string())},
            {"abilityPoint", QString::number(abilityPoint.as<int>())},
            {"moodMax", QString::number(moodMax.as<int>())},
            {"mood", QString::number(mood.as<int>())},
            {"mine", QString::number(mine.as<int>())},
            {"herbal", QString::number(herbal.as<int>())},
            {"symbol", QString::number(symbol.as<int>())},
            {"geomancy", QString::number(geomancy.as<int>())},
            {"refineWeapon", QString::number(refineWeapon.as<int>())},
            {"refineElixir", QString::number(refineElixir.as<int>())},
            {"finger", QString::number(finger.as<int>())},
            {"palm", QString::number(palm.as<int>())},
            {"fist", QString::number(fist.as<int>())},
            {"blade", QString::number(blade.as<int>())},
            {"spear", QString::number(spear.as<int>())},
            {"sword", QString::number(sword.as<int>())},
            {"wood", QString::number(wood.as<int>())},
            {"earth", QString::number(earth.as<int>())},
            {"wind", QString::number(wind.as<int>())},
            {"thunder", QString::number(thunder.as<int>())},
            {"froze", QString::number(froze.as<int>())},
            {"fire", QString::number(fire.as<int>())},
            {"magicFree", QString::number(magicFree.as<int>())},
            {"physicalFree", QString::number(physicalFree.as<int>())},
            {"race", QString::number(race.as<int>())},
            {"sex", QString::number(sex.as<int>())},
            {"moveSpeed", QString::number(moveSpeed.as<int>())},
            {"talent", QString::number(talent.as<int>())},
            {"spMax", QString::number(spMax.as<int>())},
            {"mpMax", QString::number(mpMax.as<int>())},
            {"hpMax", QString::number(hpMax.as<int>())},
            {"reputation", QString::number(reputation.as<int>())},
            {"guardValue", QString::number(guardValue.as<int>())},
            {"guard", QString::number(guard.as<int>())},
            {"critValue", QString::number(critValue.as<int>())},
            {"crit", QString::number(crit.as<int>())},
            {"footSpeed", QString::number(footSpeed.as<int>())},
            {"defense", QString::number(defense.as<int>())},
            {"attack", QString::number(attack.as<int>())},
            {"life", QString::number(life.as<int>()/12)},
            {"luck", QString::number(luck.as<int>())},
            {"beauty", QString::number(beauty.as<int>())},
            {"healthMax", QString::number(healthMax.as<int>())},
            {"energyMax", QString::number(energyMax.as<int>())}
        };
        return map;
//        return {};
    }else{
        return {};
    }

}

bool FileHandler2::saveFile(const QMap<QString, QString> &map)
{
    auto character = m_json.at_or_null("allUnit").at_or_null(m_nameid.toStdString()).at_or_null("q");
//    character.insert("q", QJsonArray({map["lastname"], map["firstname"]}));
    jsoncons::ojson temp(jsoncons::json_array_arg, {map["lastname"].toStdString(), map["firstname"].toStdString()});
    character.insert_or_assign("q", temp);
    character.insert_or_assign("1", map["attack"].toInt());
    character.insert_or_assign("2", map["defense"].toInt());
    character.insert_or_assign("3", map["footSpeed"].toInt());
    character.insert_or_assign("9", map["guard"].toInt());
    character.insert_or_assign("8", map["critValue"].toInt());
    character.insert_or_assign("qq", map["guardValue"].toInt());
    character.insert_or_assign("a", map["reputation"].toInt());
    character.insert_or_assign("b", map["mpMax"].toInt());
    character.insert_or_assign("c", map["hpMax"].toInt());
    character.insert_or_assign("m", map["spMax"].toInt());
    character.insert_or_assign("k", map["talent"].toInt());
    character.insert_or_assign("qw", map["moveSpeed"].toInt());
//    character.insert_or_assign("r", map["sex"].toInt());
//    character.insert_or_assign("t", map["race"].toInt());
    character.insert_or_assign("qe", map["physicalFree"].toInt());
    character.insert_or_assign("qr", map["magicFree"].toInt());
    character.insert_or_assign("qt", map["fire"].toInt());
    character.insert_or_assign("qy", map["froze"].toInt());
    character.insert_or_assign("qu", map["thunder"].toInt());
    character.insert_or_assign("qi", map["wind"].toInt());
    character.insert_or_assign("qo", map["earth"].toInt());
    character.insert_or_assign("qp", map["wood"].toInt());
    character.insert_or_assign("qa", map["sword"].toInt());
    character.insert_or_assign("qs", map["spear"].toInt());
    character.insert_or_assign("qd", map["blade"].toInt());
    character.insert_or_assign("qf", map["fist"].toInt());
    character.insert_or_assign("qg", map["palm"].toInt());
    character.insert_or_assign("qh", map["finger"].toInt());
    character.insert_or_assign("qj", map["refineElixir"].toInt());
    character.insert_or_assign("qk", map["refineWeapon"].toInt());
    character.insert_or_assign("ql", map["geomancy"].toInt());
    character.insert_or_assign("qz", map["symbol"].toInt());
    character.insert_or_assign("wq", map["herbal"].toInt());
    character.insert_or_assign("ww", map["mine"].toInt());
    character.insert_or_assign("qc", map["moodMax"].toInt());
    character.insert_or_assign("j", map["abilityPoint"].toInt());
    character.insert_or_assign("u", map["life"].toInt()*12);
    character.insert_or_assign("4", map["luck"].toInt());
    character.insert_or_assign("i", map["beauty"].toInt());
    character.insert_or_assign("z", map["healthMax"].toInt());
    character.insert_or_assign("6", map["energyMax"].toInt());

    auto allunit_q = m_json.at_or_null("allUnit").at_or_null(m_nameid.toStdString());
    allunit_q.insert_or_assign("q", character);
    auto allunit = m_json.at_or_null("allUnit");
    allunit.insert_or_assign(m_nameid.toStdString(), allunit_q);
    m_json.insert_or_assign("allUnit", allunit);
    m_ofs.open(m_jsonfile.toStdString());
    m_json.dump(m_ofs);
    m_ofs.close();

    QString file("./SaveDE&ENcry/SaveToolEn.exe");
    m_process->start(file, QStringList({m_jsonfile}));
    connect(m_process, &QProcess::finished, this, [this](){
        namespace fs = std::filesystem;
        fs::path filepath(m_jsonfile.toStdString());
        fs::remove(filepath);
        qDebug() << "Save Done" << Qt::endl;
        m_process->disconnect(this);
        emit save_done(true);
    });
//    qDebug() << "Save Done" << Qt::endl;
    return true;
}
